#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "load.h"
#include "elf.h"
#include "endian.h"

int main(int argc, char* argv[]){
	
	if(argc != 2){
		printf ("\n\nErreur d'utilisation du programme !\n\nSyntaxe : >./etape4 nom_fich.o\n\n");
		return 0;
	}

	if(!estELF(argv[1])){
		printf ("\n\nErreur d'utilisation du programme !\n\nSyntaxe : >./etape4 nom_fich.o\n\n");
		return 0;
	}

	char nom[50],c;
	int i,j;
	FILE* f;
	f = fopen(argv[1],"r");

	if(f!=NULL){
		Elf32_Off offset,offset_name;
		Elf32_Word size;

		Elf32_Ehdr header = load_header(f);
		Elf32_Shdr* sheader = load_section_headers(f);

		for(i=0;i<header.e_shnum;i++){
			if(sheader[i].sh_type==2){
				offset=sheader[i].sh_offset;
				size=sheader[i].sh_size;	
			}
			if(strcmp(getnom(f,sheader[i].sh_name),".strtab")==0){
				offset_name = sheader[i].sh_offset;
			}
		}

		Elf32_Sym* entry_stable = NULL;
		entry_stable = load_symbol_table(f);

		if(entry_stable != NULL){
			printf("Symbol table '.symtab' contains %d entries:\n",size/16);
			printf("%5s%8s%6s%-10s%-8s%-8s%3s %-8s\n","Num: ","Value","Size"," Type","Bind","Vis","Ndx","Name");
			for (i = 0; i < size/16; i++) {
				printf("%3d: ",i);
				printf("%08x",entry_stable[i].st_value);
				printf("%6x",entry_stable[i].st_size);

				if(ELF32_ST_TYPE(entry_stable[i].st_info)==0){
					printf(" %-9s","NOTYPE");
				} else if(ELF32_ST_TYPE(entry_stable[i].st_info)==1){
					printf(" %-9s","OBJECT");
				} else if(ELF32_ST_TYPE(entry_stable[i].st_info)==2){
					printf(" %-9s","FUNC");
				} else if(ELF32_ST_TYPE(entry_stable[i].st_info)==3){
					printf(" %-9s","SECTION");
				} else if(ELF32_ST_TYPE(entry_stable[i].st_info)==4){
					printf(" %-9s","FILE");
				} else if(ELF32_ST_TYPE(entry_stable[i].st_info)==13){
					printf(" %-9s","LOPROC");
				} else if(ELF32_ST_TYPE(entry_stable[i].st_info)==15){
					printf(" %-9s","HIPROC");
				} 

				if(ELF32_ST_BIND(entry_stable[i].st_info)==0){
					printf("%-8s","LOCAL");
				} else if(ELF32_ST_BIND(entry_stable[i].st_info)==1){
					printf("%-8s","GLOBAL");
				} else if(ELF32_ST_BIND(entry_stable[i].st_info)==2){
					printf("%-8s","WEAK");
				} else if(ELF32_ST_BIND(entry_stable[i].st_info)==13){
					printf("%-8s","LOPROC");
				} else if(ELF32_ST_BIND(entry_stable[i].st_info)==15){
					printf("%-8s","HIPROC");
				}

				if(entry_stable[i].st_other==0){
					printf("%-8s","DEFAULT");
				} else {
					printf("%-8x",entry_stable[i].st_other);
				}
				if(entry_stable[i].st_shndx==0){
					printf("%3s ","UND");
				} else {
					printf("%3x ",entry_stable[i].st_shndx);
				}

				int t = 0;
				fseek (f ,offset_name + entry_stable[i].st_name, SEEK_SET);
				c = (char)fgetc(f);
				while (c != '\0') {
				        nom[t] = c;
				        c = (char)fgetc(f);
				        t++;
				}
				nom[t] = c;

				printf("%-8s",nom); 
				printf("\n");
			}
		}

		fclose(f);
	}	

	return 0;
}
